home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 23 / AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso / Tools / Packer / xad / Developer / Sources / clients / Tar.c < prev    next >
C/C++ Source or Header  |  1999-11-06  |  8KB  |  273 lines

  1. #ifndef XADMASTER_TAR_C
  2. #define XADMASTER_TAR_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        Tar.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: Tar.c 1.0 (07.09.1998)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    Tar disk archiver client
  12.  
  13.  1.0   07.09.98 : first version
  14. */
  15.  
  16. #include <proto/xadmaster.h>
  17. #include <proto/exec.h>
  18. #include <dos/dos.h>
  19. #include "SDI_compiler.h"
  20. #define SDI_TO_ANSI
  21. #include "SDI_ASM_STD_protos.h"
  22.  
  23. #ifndef XADMASTERFILE
  24. #define Tar_Client        FirstClient
  25. #define NEXTCLIENT        0
  26. UBYTE version[] = "$VER: Tar 1.0 (07.09.1998)";
  27. #endif
  28. #define TAR_VERSION        1
  29. #define TAR_REVISION        0
  30.  
  31. struct TarHeader
  32. {                /* byte offset */
  33.   UBYTE th_Name[100];        /*   0 */
  34.   UBYTE th_Mode[8];        /* 100 */
  35.   UBYTE th_UserID[8];        /* 108 */
  36.   UBYTE th_GroupID[8];        /* 116 */
  37.   UBYTE th_Size[12];        /* 124 */
  38.   UBYTE th_MTime[12];        /* 136 */
  39.   UBYTE th_Checksum[8];     /* 148 */
  40.   UBYTE th_Typeflag;        /* 156 */
  41.   UBYTE th_LinkName[100];    /* 157 */
  42.   UBYTE th_Magic[6];        /* 257 */
  43.   UBYTE th_Version[2];        /* 263 */
  44.   UBYTE th_UserName[32];    /* 265 */
  45.   UBYTE th_GroupName[32];    /* 297 */
  46.   UBYTE th_DevMajor[8];     /* 329 */
  47.   UBYTE th_DevMinor[8];     /* 337 */
  48.   UBYTE th_Prefix[155];     /* 345 */
  49.   UBYTE th_Pad[12];        /* 500 */
  50. };
  51.  
  52. /* Values used in Typeflag field.  */
  53. #define TF_FILE     '0'  /* Regular file */
  54. #define TF_AFILE    '\0' /* Regular file */
  55. #define TF_LINK     '1'  /* Link */
  56. #define TF_SYM        '2'  /* Reserved - but GNU tar uses this for links... */
  57. #define TF_CHAR     '3'  /* Character special */
  58. #define TF_BLOCK    '4'  /* Block special */
  59. #define TF_DIR        '5'  /* Drawer */
  60. #define TF_FIFO     '6'  /* FIFO special */
  61. #define TF_CONT     '7'  /* Reserved */
  62.  
  63. /* Bits used in the mode field, values in octal.  */
  64. #define TM_SUID       04000 /* Set UID on execution */
  65. #define TM_SGID       02000 /* Set GID on execution */
  66. #define TM_SVTX       01000 /* Reserved */
  67.     /* File permissions */
  68. #define TM_UREAD      00400 /* Read by owner */
  69. #define TM_UWRITE     00200 /* Write by owner */
  70. #define TM_UEXEC      00100 /* Execute/search by owner */
  71. #define TM_GREAD      00040 /* Read by group */
  72. #define TM_GWRITE     00020 /* Write by group */
  73. #define TM_GEXEC      00010 /* Execute/search by group */
  74. #define TM_OREAD      00004 /* Read by other */
  75. #define TM_OWRITE     00002 /* Write by other */
  76. #define TM_OEXEC     00001 /* Execute/search by other */
  77.  
  78. static ULONG octtonum(STRPTR oct, LONG width, LONG *ok)
  79. {
  80.   ULONG i = 0;
  81.  
  82.   while(width-- && *oct == ' ')
  83.     ++oct;
  84.  
  85.   while(width-- && *oct >= '0' && *oct <= '7')
  86.    i = (i*8)+*(oct++)-'0';
  87.  
  88.   if(width > 0 && *oct)    /* an error, set error flag */
  89.     *ok = 0;
  90.  
  91.   return i;
  92. }
  93.  
  94. BOOL checktarsum(struct TarHeader *th)
  95. {
  96.   LONG sc, i;
  97.   ULONG uc, checks;
  98.   
  99.   i = 1;
  100.   checks = octtonum(th->th_Checksum, 8, &i);
  101.   if(!i)
  102.     return DOSFALSE;
  103.  
  104.   for(i = sc = uc = 0; i < 512; ++i)
  105.   {
  106.     sc += ((BYTE *) th)[i];
  107.     uc += ((UBYTE *) th)[i];
  108.   }
  109.   
  110.   for(i = 148; i < 156; ++i)
  111.   {
  112.     sc -= ((BYTE *) th)[i];
  113.     uc -= ((UBYTE *) th)[i];
  114.   }
  115.   sc += 8 * ' ';
  116.   uc += 8 * ' ';
  117.   
  118.   if(checks != uc && checks != (ULONG) sc)
  119.     return DOSFALSE;
  120.   return DOSTRUE;
  121. }
  122.  
  123. ASM(BOOL) Tar_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  124. REG(a6, struct xadMasterBase *xadMasterBase))
  125. {
  126.   if(data[0] > 0x1F && checktarsum((struct TarHeader *) data))
  127.     return 1;
  128.   else
  129.     return 0;
  130. }
  131.  
  132. ASM(LONG) Tar_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  133. REG(a6, struct xadMasterBase *xadMasterBase))
  134. {
  135.   struct TarHeader th;
  136.   struct xadFileInfo *fi = 0, *fi2;
  137.   LONG err, size, ok, a, b, d, i, pos, num = 1;
  138.   struct ExecBase * SysBase = xadMasterBase->xmb_SysBase;
  139.  
  140.   while(!(err = xadHookAccess(XADAC_READ, sizeof(struct TarHeader), &th, ai)))
  141.   {
  142.     if(!th.th_Name[0])
  143.       break;
  144.     ok = checktarsum(&th); /* check checksum and init ok */
  145.     size = octtonum(th.th_Size, 12, &ok);
  146.  
  147.     pos = ai->xai_InPos;
  148.     if(ok && (th.th_Typeflag == TF_FILE || 
  149.     th.th_Typeflag == TF_AFILE) &&
  150.     err != xadHookAccess(XADAC_INPUTSEEK, (size+511)&~511, 0, ai))
  151.       ok = 0;
  152.     if(ok && (th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_AFILE ||
  153.     th.th_Typeflag == TF_DIR || th.th_Typeflag == TF_SYM ||
  154.     th.th_Typeflag == TF_LINK))
  155.     {
  156.       a = strlen(th.th_Name) + 1;
  157.       if(th.th_Name[a-2] == '/')
  158.       {
  159.     if(th.th_Typeflag == TF_AFILE || th.th_Typeflag == TF_FILE)
  160.     {
  161.       th.th_Name[--a-1] == 0;
  162.           th.th_Typeflag = TF_DIR;
  163.         }
  164.       }
  165.       
  166.       b = th.th_LinkName[0] ? 1 + strlen(th.th_LinkName) : 0;
  167.       i = th.th_UserName[0] ? 1 + strlen(th.th_UserName) : 0;
  168.       d = th.th_GroupName[0] ? 1 + strlen(th.th_GroupName) : 0;
  169.       
  170.       if(!(fi2 = (struct xadFileInfo *) xadAllocObject(XADOBJ_FILEINFO,
  171.       XAD_OBJNAMESIZE, a+b+i+d, TAG_DONE)))
  172.       {
  173.         err = XADERR_NOMEMORY; break;
  174.       }
  175.       else
  176.       {
  177.         fi2->xfi_PrivateInfo = (APTR) pos;
  178.     if(th.th_Typeflag == TF_LINK || th.th_Typeflag == TF_SYM)
  179.       fi2->xfi_Flags |= XADFIF_LINK;
  180.     else if(th.th_Typeflag == TF_DIR)
  181.     {
  182.       fi2->xfi_Flags |= XADFIF_DIRECTORY;
  183.       size = 0;
  184.     }
  185.         fi2->xfi_CrunchSize = fi2->xfi_Size = size;
  186.         CopyMem(th.th_Name, fi2->xfi_FileName, a-1);
  187.         if(b)
  188.         {
  189.           fi2->xfi_LinkName = fi2->xfi_FileName + a;
  190.           CopyMem(th.th_LinkName, fi2->xfi_LinkName, b-1);
  191.         }
  192.         if(i)
  193.         {
  194.           fi2->xfi_UserName = fi2->xfi_FileName + a + b;
  195.           CopyMem(th.th_UserName, fi2->xfi_UserName, i-1);
  196.         }
  197.         if(d)
  198.         {
  199.           fi2->xfi_GroupName = fi2->xfi_FileName + a + b + i;
  200.           CopyMem(th.th_GroupName, fi2->xfi_GroupName, d-1);
  201.         }
  202.         fi2->xfi_OwnerUID = octtonum(th.th_UserID, 8, &ok);
  203.         fi2->xfi_OwnerGID = octtonum(th.th_GroupID, 8, &ok);
  204.  
  205.     i = octtonum(th.th_Mode, 8, &ok);
  206.     if(!(i & TM_UREAD))    fi2->xfi_Protection |= FIBF_READ;
  207.     if(!(i & TM_UWRITE))    fi2->xfi_Protection |= FIBF_WRITE;
  208.     if(!(i & TM_UEXEC))    fi2->xfi_Protection |= FIBF_EXECUTE;
  209.     if(i & TM_GREAD)    fi2->xfi_Protection |= FIBF_GRP_READ;
  210.     if(i & TM_GWRITE)    fi2->xfi_Protection |= FIBF_GRP_WRITE;
  211.     if(i & TM_GEXEC)    fi2->xfi_Protection |= FIBF_GRP_EXECUTE;
  212.     if(i & TM_OREAD)    fi2->xfi_Protection |= FIBF_OTR_READ;
  213.     if(i & TM_OWRITE)    fi2->xfi_Protection |= FIBF_OTR_WRITE;
  214.     if(i & TM_OEXEC)    fi2->xfi_Protection |= FIBF_OTR_EXECUTE;
  215.  
  216.         err = xadConvertDates(XAD_DATEUNIXUTC, octtonum(th.th_MTime, 12, &ok),
  217.         XAD_GETDATEXADDATE, &fi2->xfi_Date, TAG_DONE);
  218.  
  219.     if(ok && !err)
  220.     {
  221.       fi2->xfi_EntryNumber = num++;
  222.           if(fi)
  223.             fi->xfi_Next = fi2;
  224.           else
  225.             ai->xai_FileInfo = fi2;
  226.           fi = fi2;
  227.         }
  228.         else
  229.           xadFreeObjectA(fi2, 0);
  230.       }
  231.     }
  232.     if(!ok)
  233.       ai->xai_Flags |= XADAIF_FILECORRUPT;
  234.   }
  235.  
  236.   return err;
  237. }
  238.  
  239. ASM(LONG) Tar_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  240. REG(a6, struct xadMasterBase *xadMasterBase))
  241. {
  242.   LONG i;
  243.  
  244.   if((i = ((LONG) (ai->xai_CurFile->xfi_PrivateInfo)) - ai->xai_InPos))
  245.     if((i = xadHookAccess(XADAC_INPUTSEEK, i, 0, ai)))
  246.       return i;
  247.  
  248.   return xadHookAccess(XADAC_COPY, ai->xai_CurFile->xfi_Size, 0, ai);
  249. }
  250.  
  251. ASM(void) Tar_Free(REG(a0, struct xadArchiveInfo *ai),
  252. REG(a6, struct xadMasterBase *xadMasterBase))
  253. {
  254.   struct xadFileInfo *fi, *fi2;
  255.  
  256.   fi = ai->xai_FileInfo;
  257.   while(fi)
  258.   {
  259.     fi2 = fi->xfi_Next;
  260.     xadFreeObjectA(fi, 0);
  261.     fi = fi2;
  262.   }
  263.   ai->xai_FileInfo = 0;
  264. }
  265.  
  266. struct xadClient Tar_Client = {
  267. NEXTCLIENT, XADCLIENT_VERSION, 1, TAR_VERSION, TAR_REVISION,
  268. 512, XADCF_FILEARCHIVER, XADCID_TAR, "Tar",
  269. (BOOL (*)()) Tar_RecogData, (LONG (*)()) Tar_GetInfo,
  270. (LONG (*)()) Tar_UnArchive, (void (*)()) Tar_Free};
  271.  
  272. #endif /* XADASTER_TAR_C */
  273.